package com.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.controller.reqdto.*;
import com.controller.respdto.GroupList;
import com.controller.respdto.GroupListParam;
import com.controller.respdto.PcList;
import com.enums.CommonEnum;
import com.repository.mapper.AddressMapper;
import com.repository.mapper.GroupMsgMapper;
import com.repository.mapper.PcGroupRelationshipMapper;
import com.repository.mapper.PcMessageMapper;
import com.repository.po.Address;
import com.repository.po.GroupMsg;
import com.repository.po.PcGroupRelationship;
import com.repository.po.PcMessage;
import com.service.GroupService;
import com.service.PcService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author Ruiwen
 * @since 2024-11-19
 */
@Service
public class GroupServiceImpl implements GroupService {
    @Resource
    GroupMsgMapper groupMsgMapper;

    @Resource
    PcGroupRelationshipMapper pcGroupRelationshipMapper;
    @Resource
    PcMessageMapper pcMessageMapper;
    @Resource
    AddressMapper addressMapper;


    @Override
    public Boolean addGroup(GroupAddParam groupAddParam) {
        //校验
        List<GroupMsg> dbGroupMsgList = groupMsgMapper.selectList(new QueryWrapper<GroupMsg>().eq("group_name", groupAddParam.getGroupName()));
        if (Objects.nonNull(dbGroupMsgList) && dbGroupMsgList.size() > 0) {
            throw new RuntimeException("群组名称已存在,请勿重复添加");
        }
        //1、先添加群组
        GroupMsg groupMsg = new GroupMsg();
        BeanUtils.copyProperties(groupAddParam, groupMsg);
        groupMsgMapper.insert(groupMsg);
        //2、添加群组和pc的关系
        List<Integer> pcIdList = groupAddParam.getPcIds();
        addRelationShip(groupMsg.getId(), pcIdList);
        return Boolean.TRUE;
    }

    @Override
    public Boolean updateGroup(GroupUpdateParam updateParam) {
        GroupMsg groupMsg = new GroupMsg();
        BeanUtils.copyProperties(updateParam, groupMsg);
        groupMsgMapper.updateById(groupMsg);
        //删除原有关系
        pcGroupRelationshipMapper.delete(new QueryWrapper<PcGroupRelationship>().eq("group_id", updateParam.getId()));
        //添加新关系
        List<Integer> pcIds = updateParam.getPcIds();
        addRelationShip(updateParam.getId(), pcIds);
        return Boolean.TRUE;
    }

    public Boolean addRelationShip(Integer groupId, List<Integer> pcIds) {
        pcIds.forEach(pcId -> {
            PcGroupRelationship pcGroupRelationship = new PcGroupRelationship();
            pcGroupRelationship.setGroupId(groupId);
            pcGroupRelationship.setPcId(pcId);
            pcGroupRelationshipMapper.insert(pcGroupRelationship);
        });
        return Boolean.TRUE;
    }

    @Override
    public GroupList queryGroup(GroupQueryParam queryParam) {
        synchronized (this) {
            List<GroupMsg> groupMsgs = groupMsgMapper.selectList(null);
            //根据状态筛选
            if (Objects.nonNull(queryParam.getGroupStatus())) {
                List<GroupMsg> collect = groupMsgs.stream().filter(groupMsg -> groupMsg.getGroupStatus().equals(CommonEnum.GROUP_NOT_RUN.getCode())).collect(Collectors.toList());
                if (collect.size() <= 0) {
                    //新建群组
                    GroupMsg groupMsg = new GroupMsg();
                    //群组明随机生成 +时间戳
                    String name = System.currentTimeMillis() + "";
                    groupMsg.setGroupName(name);
                    groupMsg.setGroupStatus(CommonEnum.GROUP_NOT_RUN.getCode());
                    groupMsgMapper.insert(groupMsg);
                }
            }
        }
        Page<GroupMsg> page = new Page<GroupMsg>(queryParam.getPage(), queryParam.getLimit());
        QueryWrapper<GroupMsg> queryWrapper = new QueryWrapper<>();
        if (Objects.nonNull(queryParam.getGroupName())) {
            queryWrapper.like("group_name", queryParam.getGroupName());
        }
        if (Objects.nonNull(queryParam.getGroupStatus())) {
            queryWrapper.eq("group_status", queryParam.getGroupStatus());
        }
        if (Objects.nonNull(queryParam.getCreateUserName())) {
            queryWrapper.like("create_user_name", queryParam.getCreateUserName());
        }
        if (Objects.nonNull(queryParam.getCreateUserPhone())) {
            queryWrapper.like("create_user_phone", queryParam.getCreateUserPhone());
        }
        if (Objects.nonNull(queryParam.getStartTime())) {
            queryWrapper.ge("run_time", queryParam.getStartTime());
        }
        if (Objects.nonNull(queryParam.getEndTime())) {
            queryWrapper.le("run_time", queryParam.getEndTime());
        }
        queryWrapper.orderByDesc("create_time");
        Page<GroupMsg> groupMsgPage = groupMsgMapper.selectPage(page, queryWrapper);
        List<GroupMsg> groupMsgList = groupMsgPage.getRecords();
        //遍历addRelationShip
        List<GroupListParam> groupListParams = new ArrayList<>();
        groupMsgList.forEach(groupMsg -> {
            GroupListParam groupListParam = new GroupListParam();
            groupListParam.setGroupMsg(groupMsg);
            groupListParam.setPcMessages(getGroupPcMessage(groupMsg));
            groupListParams.add(groupListParam);

        });

        return GroupList.builder().groupLists(groupListParams).total(groupMsgPage.getTotal()).build();
    }

    private List<PcMessage> getGroupPcMessage(GroupMsg groupMsg) {
        List<PcMessage> pcMessages = new ArrayList<>();
        List<PcGroupRelationship> pcGroupRelationshipList = pcGroupRelationshipMapper.selectList(new QueryWrapper<PcGroupRelationship>().eq("group_id", groupMsg.getId()));
        pcGroupRelationshipList.forEach(pcGroupRelationship -> {
            PcMessage pcMessage = pcMessageMapper.selectById(pcGroupRelationship.getPcId());
            if (Objects.nonNull(pcMessage.getAddressId())) {
                Address address = addressMapper.selectById(pcMessage.getAddressId());
                if (Objects.nonNull(address)) {
                    pcMessage.setAddressName(address.getName());
                    pcMessage.setAddress(address.getAddress());
                } else {
                    pcMessage.setAddressName("暂无地区");
                    pcMessage.setAddress("暂无地区地址");
                }
            }
            pcMessages.add(pcMessage);
        });
        return pcMessages;
    }

    @Override
    public Boolean deleteGroup(String groupId) {
        //删除群组
        groupMsgMapper.deleteById(groupId);
        //删除关系
        pcGroupRelationshipMapper.delete(new QueryWrapper<PcGroupRelationship>().eq("group_id", groupId));
        return Boolean.TRUE;
    }

    @Override
    public Boolean joinGroup(JoinGroupParam joinGroupParam) {
        PcGroupRelationship relationship = pcGroupRelationshipMapper.selectOne(new QueryWrapper<PcGroupRelationship>().eq("group_id", joinGroupParam.getGroupId()).eq("pc_id", joinGroupParam.getPcId()));
        if (Objects.nonNull(relationship)) {
            throw new RuntimeException("已加入该群组,请勿重复加入");
        }
        PcGroupRelationship pcGroupRelationship = new PcGroupRelationship();
        pcGroupRelationship.setGroupId(joinGroupParam.getGroupId());
        pcGroupRelationship.setPcId(joinGroupParam.getPcId());
        pcGroupRelationshipMapper.insert(pcGroupRelationship);

        PcMessage pcMessage = new PcMessage();
        pcMessage.setId(joinGroupParam.getPcId());
        pcMessage.setPcStatus(CommonEnum.PC_READY.getCode());
        pcMessageMapper.updateById(pcMessage);
        return Boolean.TRUE;
    }

    @Override
    public Boolean exitGroup(ExitGroupParam exitGroupParam) {
        pcGroupRelationshipMapper.delete(new QueryWrapper<PcGroupRelationship>().eq("group_id", exitGroupParam.getGroupId()).eq("pc_id", exitGroupParam.getPcId()));

        PcMessage pcMessage = new PcMessage();
        pcMessage.setId(exitGroupParam.getPcId());
        pcMessage.setPcStatus(CommonEnum.PC_NOT_RUN.getCode());
        pcMessageMapper.updateById(pcMessage);
        return Boolean.TRUE;
    }
}
